using TerritoryGame.Domain.Interfaces;
using Microsoft.Extensions.DependencyInjection;
using TerritoryGame.Application.Interfaces;

namespace TerritoryGame.Application.Services;

/// <summary>
/// 领域事件发布器实现
/// </summary>
public class DomainEventPublisher : IDomainEventPublisher
{
    private readonly IServiceProvider _serviceProvider;
    private readonly IAppLogService _logService;

    public DomainEventPublisher(IServiceProvider serviceProvider, IAppLogService logService)
    {
        _serviceProvider = serviceProvider;
        _logService = logService;
    }

    public async Task PublishAsync<T>(T domainEvent) where T : IDomainEvent
    {
        try
        {
            // 获取所有注册的事件处理器
            var handlers = _serviceProvider.GetServices<IDomainEventHandler<T>>();
            
            if (!handlers.Any())
            {
                _logService.LogWarning($"未找到事件 {typeof(T).Name} 的处理器");
                return;
            }

            // 并行执行所有处理器
            var tasks = handlers.Select(handler => handler.HandleAsync(domainEvent));
            await Task.WhenAll(tasks);

            _logService.LogInformation($"事件 {typeof(T).Name} 发布成功，处理了 {handlers.Count()} 个处理器");
        }
        catch (Exception ex)
        {
            _logService.LogError($"发布事件 {typeof(T).Name} 时发生错误", ex);
            throw;
        }
    }

    public async Task PublishAsync(IEnumerable<IDomainEvent> domainEvents)
    {
        foreach (var domainEvent in domainEvents)
        {
            // 使用反射调用泛型方法
            var method = typeof(DomainEventPublisher).GetMethod(nameof(PublishAsync), new[] { typeof(IDomainEvent) });
            if (method != null)
            {
                await (Task)method.Invoke(this, new object[] { domainEvent })!;
            }
        }
    }
} 